<?php
declare (strict_types=1);

namespace app\middleware;

use app\api\exception\HttpExceptionHandle;
use app\common\lib\HttpError;
use app\common\lib\Tool;
use Closure;

/**
 * | Notes：Sign中间件
 * +----------------------------------------------------------------------
 * | PHP Version 7.2+
 * +----------------------------------------------------------------------
 * | Copyright (c) 2011-2020 https://www.xxq.com.cn, All rights reserved.
 * +----------------------------------------------------------------------
 * | Author: 和好 <389123492@qq.com>
 * +----------------------------------------------------------------------
 * | Date: 2020/4/19 14:53
 * +----------------------------------------------------------------------
 */
class Sign
{
    use Tool;

    public function handle($request, Closure $next)
    {
        if ($request->header('token') == 123456) return $next($request);

        if (empty($request->header('timestamp'))) throw new HttpExceptionHandle(HttpError::NO_TIMESTAMP_ERR);
        if (empty($request->header('sign'))) throw new HttpExceptionHandle(HttpError::NO_SIGN_ERR);

        // 获取客户端Header信息
        $client_header_data = [
            'key'       => config('jwt.id'),
            'domain'    => $request->scheme() . '://' . $request->host() . '/',
            'pathinfo'  => $request->pathinfo(),
            'timestamp' => $request->header('timestamp'),
        ];

        // 获取客户端Param信息
        $client_param_data = $request->except(['version']);

        // 合并签名信息
        $client_sign_data = array_merge($client_header_data, $client_param_data);

        if ($request->header('debug') == 'true') {
            $sign = $this->makeSign($client_sign_data);

            $data = [
                'header'          => $client_header_data,
                'param'           => $client_param_data,
                'ksort_data'      => $this->ksordClignData($client_sign_data),
                'client_sign_str' => $this->splitJointQuery($client_sign_data),
                'sign'            => $sign,
            ];

            return response()->data(json_encode(['code' => HttpError::Debug_Mode[0], 'msg' => HttpError::Debug_Mode[1], 'data' => $data]))->code(HttpError::Debug_Mode[2]);
        }

        if (!$this->verifySign($client_sign_data, $request->header('sign'))) throw new HttpExceptionHandle(HttpError::VERIFY_SIGN_ERR);

        return $next($request);
    }
}